﻿#include "idcardreaddatang.h"
#include <QDebug>
#include <qt_windows.h>

#ifdef  _WIN32
#define STDCALL  __stdcall

#else

#define STDCALL
#endif
#ifndef SDTAPI_
#define SDTAPI_

#ifdef __cplusplus
extern "C"{
#endif
/**********************************************************
 ********************** 端口类API *************************
 **********************************************************/
int STDCALL SDT_GetCOMBaud(int iPort, unsigned int *puiBaudRate);
int STDCALL SDT_SetCOMBaud(int iPort, unsigned int uiCurrBaud, unsigned int uiSetBaud);
int STDCALL SDT_OpenPort(int iPort);
int STDCALL SDT_ClosePort(int iPort);


/**********************************************************
 ********************** SAM类API **************************
 **********************************************************/
int STDCALL SDT_ResetSAM(int iPort, int iIfOpen);
int STDCALL SDT_SetMaxRFByte(int iPort, unsigned char ucByte, int bIfOpen);
int STDCALL SDT_GetSAMStatus(int iPort, int iIfOpen);
int STDCALL SDT_GetSAMID(int iPort, unsigned char * pucSAMID, int iIfOpen);
int STDCALL SDT_GetSAMIDToStr(int iPort, char *pcSAMID, int iIfOpen);

/**********************************************************
 ******************* 身份证卡类API ************************
 **********************************************************/
int	STDCALL SDT_StartFindIDCard(int iPort, unsigned char *pucManaInfo, int iIfOpen);
int	STDCALL SDT_SelectIDCard(int iPort, unsigned char *pucManaMsg, int iIfOpen);
int	STDCALL SDT_ReadBaseMsg(int iPort, unsigned char *pucCHMsg, unsigned int *puiCHMsgLen, unsigned char *pucPHMsg, unsigned int *puiPHMsgLen, int iIfOpen);
int	STDCALL SDT_ReadBaseMsgToFile(int iPort, char *pcCHMsgFileName, unsigned int *puiCHMsgFileLen, char *pcPHMsgFileName, unsigned int *puiPHMsgFileLen, int iIfOpen);
int	STDCALL SDT_ReadBaseFPMsg(int iPort, unsigned char *pucCHMsg, unsigned int *puiCHMsgLen, unsigned char *pucPHMsg, unsigned int *puiPHMsgLen, unsigned char *pucFPMsg, unsigned int *puiFPMsgLen, int iIfOpen);
int	STDCALL SDT_ReadBaseFPMsgToFile(int iPort, char *pcCHMsgFileName, unsigned int *puiCHMsgFileLen, char *pcPHMsgFileName, unsigned int *puiPHMsgFileLen, char *pcFPMsgFileName, unsigned int *puiFPMsgFileLen, int iIfOpen);
int	STDCALL SDT_ReadNewAppMsg(int iPort, unsigned char *pucAppMsg, unsigned int *puiAppMsgLen, int iIfOpen);
#ifdef __cplusplus
}
#endif
#endif

typedef int (WINAPI*GETBMP)(char* file_name, int intf);  /*获得身份证图片*/
GETBMP        _GetBmp;      /*解码身份证头像图片*/

unsigned char idtextinfo[2310+4];
unsigned char pucFPMsg[1024];
bool FPExist;
//typedef int (WINAPI*GETBMP)(char* file_name, int intf);

IDCardReadDatang::IDCardReadDatang(QObject *parent):QThread(parent)
{
    m_bStop = false;
    m_nUsbPort = 0;

    m_strListFork<<QString::fromLocal8Bit("汉") \
                 <<QString::fromLocal8Bit("蒙古") \
                 <<QString::fromLocal8Bit("回") \
                 <<QString::fromLocal8Bit("藏") \
                 <<QString::fromLocal8Bit("维吾尔") \
                 <<QString::fromLocal8Bit("苗") \
                 <<QString::fromLocal8Bit("彝") \
                 <<QString::fromLocal8Bit("壮") \
                 <<QString::fromLocal8Bit("布依") \
                 <<QString::fromLocal8Bit("朝鲜") \
                 <<QString::fromLocal8Bit("满") \
                 <<QString::fromLocal8Bit("侗") \
                 <<QString::fromLocal8Bit("瑶") \
                 <<QString::fromLocal8Bit("白") \
                 <<QString::fromLocal8Bit("土家") \
                 <<QString::fromLocal8Bit("哈尼") \
                 <<QString::fromLocal8Bit("哈萨克") \
                 <<QString::fromLocal8Bit("傣") \
                 <<QString::fromLocal8Bit("黎") \
                 <<QString::fromLocal8Bit("傈僳") \
                 <<QString::fromLocal8Bit("佤") \
                 <<QString::fromLocal8Bit("畲") \
                 <<QString::fromLocal8Bit("高山") \
                 <<QString::fromLocal8Bit("拉祜") \
                 <<QString::fromLocal8Bit("水") \
                 <<QString::fromLocal8Bit("东乡") \
                 <<QString::fromLocal8Bit("纳西") \
                 <<QString::fromLocal8Bit("景颇") \
                 <<QString::fromLocal8Bit("柯尔克孜") \
                 <<QString::fromLocal8Bit("土") \
                 <<QString::fromLocal8Bit("达斡尔") \
                 <<QString::fromLocal8Bit("仫佬") \
                 <<QString::fromLocal8Bit("羌") \
                 <<QString::fromLocal8Bit("布朗") \
                 <<QString::fromLocal8Bit("撒拉") \
                 <<QString::fromLocal8Bit("毛南") \
                 <<QString::fromLocal8Bit("仡佬") \
                 <<QString::fromLocal8Bit("锡伯") \
                 <<QString::fromLocal8Bit("阿昌") \
                 <<QString::fromLocal8Bit("普米") \
                 <<QString::fromLocal8Bit("塔吉克") \
                 <<QString::fromLocal8Bit("怒") \
                 <<QString::fromLocal8Bit("乌孜别克") \
                 <<QString::fromLocal8Bit("俄罗斯") \
                 <<QString::fromLocal8Bit("鄂温克") \
                 <<QString::fromLocal8Bit("德昂") \
                 <<QString::fromLocal8Bit("保安") \
                 <<QString::fromLocal8Bit("裕固") \
                 <<QString::fromLocal8Bit("京") \
                 <<QString::fromLocal8Bit("塔塔尔") \
                 <<QString::fromLocal8Bit("独龙") \
                 <<QString::fromLocal8Bit("鄂伦春") \
                 <<QString::fromLocal8Bit("赫哲") \
                 <<QString::fromLocal8Bit("门巴") \
                 <<QString::fromLocal8Bit("珞巴") \
                 <<QString::fromLocal8Bit("其他") \
                 <<QString::fromLocal8Bit("其他") \
                 <<QString::fromLocal8Bit("基诺") \
                 <<QString::fromLocal8Bit("其他");

}

IDCardReadDatang::~IDCardReadDatang()
{
    m_bStop = true;
    quit();
    wait();
}

bool IDCardReadDatang::initIdCard()
{       
    for (int iPort=1001; iPort<=1016; iPort++)
    {//find idcard port
        SDT_ClosePort(iPort);
        if(0x90 == SDT_OpenPort(iPort))
        {
            m_nUsbPort = iPort;
            break;
        }
    }

    if(m_nUsbPort == 0) return false;
    //load bmp decode dll
    HINSTANCE hInstLibrary = LoadLibrary(L"WltRS.dll");
    if (hInstLibrary == NULL)
    {
        return false;
    }
    else
    {
        _GetBmp = (GETBMP)GetProcAddress(hInstLibrary,"GetBmp");
        if(_GetBmp == NULL)
        {
            FreeLibrary(hInstLibrary);
            return false;
        }
    }

    return true;
}

bool IDCardReadDatang::readIdCard()
{
    int ret=0;
    unsigned char pucManaInfo[4] = {0x00};
    if ( 0x9F != SDT_StartFindIDCard(m_nUsbPort,pucManaInfo,0))
    {
          //m_IDinfo = "    寻卡失败：";
       return false;
    }

    int iValid;
    int id_txt_size;
    int id_photo_size;
    unsigned char pucManaMsg[8] = {0x00};
    memset(pucManaMsg,0x00,sizeof(pucManaMsg));

    iValid = SDT_SelectIDCard(m_nUsbPort,pucManaMsg,0);
    if (iValid != 0x90)
    {
        ret = -3;
    }
    else
    {
      iValid =   SDT_ReadBaseFPMsg(m_nUsbPort,(unsigned char *)idtextinfo,
                    (unsigned int *)&id_txt_size,(unsigned char *)(idtextinfo+256),(unsigned int *)&id_photo_size,
                    pucFPMsg, &uiFPMsgLen, 0);
      if(iValid == 0x21)//"此安全控制模块不支持 SDT_ReadBaseFPMsg 接口!
      {
          iValid = SDT_ReadBaseMsg(m_nUsbPort,(unsigned char *)idtextinfo,
                (unsigned int *)&id_txt_size,(unsigned char *)(idtextinfo+256),(unsigned int *)&id_photo_size,0);
      }
      if(uiFPMsgLen)
      {
          FPExist = true;
      }
      else
      {
          FPExist = false;
      }

    /*读取新地址信息*/
      memset(newaddstr,0,72);
      unsigned int new_addr_size = 0;
      SDT_ReadNewAppMsg(m_nUsbPort,(unsigned char *)newaddstr,&new_addr_size,0);
      //0x90 ok 0x91:本身份证无追加信息

       if (iValid != 0x90)
       {
          ret =  -4;
       }
       else if(iValid==0x37)
       {
            ret =  -6;
       }
       else
       {
          if (id_txt_size != 256 || id_photo_size != 1024)
          {
             ret = -5;
          }
       }
    }

    bool retb=false;

    switch(ret)
    {
    case 0:
         // m_IDinfo += L"身份证信息读取成功!\n";

          retb = true;
        break;
    case -3:
       // m_IDinfo = L"选卡失败";
        break;
    case -4:
       // m_IDinfo = L"读卡失败";
        break;
    case -5:
       // m_IDinfo = L"读卡信息长度错误";
        break;
    case -6:
       // m_IDinfo = L"指纹信息验证错误";
        break;
    default:
       // m_IDinfo = L"读卡异常";
        break;
    }

    //======================
    if (retb)
    {
         // m_IDinfo = "    身份证文字信息：";
          if((idtextinfo[248]==73) && (idtextinfo[249]==0x0))
          {
             // m_IDinfo += "\r\n英文姓名：";
              char szEnName[120]={0};
              memcpy(szEnName,idtextinfo,120);
             // m_IDinfo += szEnName;
            //  m_IDinfo += "\r\n中文姓名：";
              char szName[30]={0};
              memcpy(szName,idtextinfo+120+2+30+6,30);            
            //  m_IDinfo += szName;
            //  m_IDinfo += "\r\n性别：";
            char sexstr[2+2] = {0x00};
            memcpy(sexstr,idtextinfo+120,2);
            QString sexcode = sexstr;
            if(sexcode == "1") sexcode = "男 / M";
            else if(sexcode == "2")sexcode = "女 / F";
            else if(sexcode == "0")sexcode = "未知";
            else if(sexcode == "9")sexcode = "未说明";
            else sexcode = "无效";
           // m_IDinfo += sexcode;
          //    m_IDinfo += "\r\n生日：";
            char szBirthday[16]={0};
            memcpy(szBirthday,idtextinfo+120+2+30+6+30+32,16);
           // m_IDinfo +=szBirthday;
          // m_IDinfo += "\r\n国籍：";
           char szNation[6]={0};
           memcpy(szNation,idtextinfo+120+2+30,6);
         //  m_IDinfo += szNation;
          // m_IDinfo += "\r\n有效期：";
          char szValidDate[32]={0};
          memcpy(szValidDate,idtextinfo+120+2+30+6+30,32);
        //  m_IDinfo +=szValidDate;
         //   m_IDinfo += "\r\n证件号码：";
          char szCardNo[30]={0};
          memcpy(szCardNo,idtextinfo+120+2,30);
        //  m_IDinfo +=szCardNo;
        }
        else
        {
             WCHAR wszName[16]={0};
             memcpy(wszName,idtextinfo,30);
             m_stID_INFO.strName = QString::fromWCharArray(wszName);

             WCHAR wszSex[4] = {0x00};
             memcpy(wszSex,idtextinfo+30,2);
             int nSexType = QString::fromWCharArray(wszSex).toInt();
             if(nSexType == 1)
             {
                m_stID_INFO.strSex  = QString::fromLocal8Bit("男");
             }
             else if(nSexType == 2)
             {
                m_stID_INFO.strSex  = QString::fromLocal8Bit("女");
             }
             else if(nSexType == 0)
             {
                m_stID_INFO.strSex  = QString::fromLocal8Bit("未知");
             }
             else if(nSexType == 9)
             {
                m_stID_INFO.strSex  = QString::fromLocal8Bit("未说明");
             }
             else
             {
                m_stID_INFO.strSex  = QString::fromLocal8Bit("无效");
             }

             int nForkType = (idtextinfo[30+2]-'0')*10 + idtextinfo[34]-'0';
             m_stID_INFO.strNation = m_strListFork[nForkType-1];

             WCHAR wszBirthday[9]={0};
             memcpy(wszBirthday,idtextinfo+30+2+4,16);
             m_stID_INFO.strBirthday = QString::fromWCharArray(wszBirthday);

             WCHAR wszAddress[36]={0};
             memcpy(wszAddress,idtextinfo+30+2+4+16,70);
             m_stID_INFO.strAddress = QString::fromWCharArray(wszAddress);

             WCHAR wszCardNo[19]={0};
             memcpy(wszCardNo,idtextinfo+30+2+4+16+70,36);
             m_stID_INFO.strIDCode =  QString::fromWCharArray(wszCardNo);

             WCHAR wszPoliceStation[30]={0};
             memcpy(wszPoliceStation,idtextinfo+30+2+4+16+70+36,30);
             m_stID_INFO.strDepartment = QString::fromWCharArray(wszPoliceStation);

             WCHAR wszValidDate[32]={0};
             memcpy(wszValidDate,idtextinfo+30+2+4+16+70+36+30,32);
             m_stID_INFO.strValideDate = QString::fromWCharArray(wszValidDate);

             //decode idcard photo
             FILE *fp = fopen("zp.wlt","wb+");
                 if (fp != NULL)
                 {
                     fwrite(idtextinfo+256,sizeof(char),1024,fp);
                     fclose(fp);
                 }
             int ret = _GetBmp("zp.wlt",2);  /*USB param:2，COM param:1*/
             if(ret < 0)
             {
                 //get photo failed
             }

             QPixmap pixMap;
             pixMap.load("zp.bmp");
             emit sigIdcardInfo(m_stID_INFO, pixMap);
          }
    }
    else{
        //MessageBox(_T("读卡失败!"));

    }

    return 0;
}

void IDCardReadDatang::run()
{
    while(!m_bStop)
    {
        if(initIdCard())
        {
            while(!m_bStop)
            {
                readIdCard();
                QThread::msleep(1);
            }
        }

        QThread::msleep(1);
    }
    qDebug("Idcard thread exit normal.\n");
}
